package com.ruoyi.system.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import javax.validation.Validator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.system.mapper.DatingMemberMapper;
import com.ruoyi.system.domain.DatingMember;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.service.IDatingMemberService;

/**
 * 婚恋人员信息Service业务层处理
 *
 * @author ruoyi
 * @date 2024-01-15
 */
@Service
public class DatingMemberServiceImpl implements IDatingMemberService
{
    private static final Logger log = LoggerFactory.getLogger(DatingMemberServiceImpl.class);

    @Autowired
    private DatingMemberMapper datingMemberMapper;

    @Autowired
    protected Validator validator;

    /**
     * 查询婚恋人员信息
     *
     * @param memberId 婚恋人员信息主键
     * @return 婚恋人员信息
     */
    @Override
    public DatingMember selectDatingMemberByMemberId(Long memberId)
    {
        return datingMemberMapper.selectById(memberId);
    }

    /**
     * 查询婚恋人员信息列表
     *
     * @param datingMember 婚恋人员信息
     * @return 婚恋人员信息
     */
    @Override
    public List<DatingMember> selectDatingMemberList(DatingMember datingMember)
    {
        return datingMemberMapper.selectDatingMemberList(datingMember);
    }

    /**
     * 新增婚恋人员信息
     *
     * @param datingMember 婚恋人员信息
     * @return 结果
     */
    @Override
    public int insertDatingMember(DatingMember datingMember)
    {
        // 校验人员编号唯一性
        if (!checkMemberNoUnique(datingMember))
        {
            throw new ServiceException("新增人员'" + datingMember.getRealName() + "'失败，人员编号已存在");
        }

        // 校验手机号唯一性
        if (!checkPhoneUnique(datingMember))
        {
            throw new ServiceException("新增人员'" + datingMember.getRealName() + "'失败，手机号码已存在");
        }

        // 自动生成人员编号（如果未提供）
        if (StringUtils.isEmpty(datingMember.getMemberNo()))
        {
            datingMember.setMemberNo(generateMemberNo());
        }

        // 根据生日自动计算年龄
        if (datingMember.getBirthDate() != null)
        {
            datingMember.setAge(calculateAge(datingMember.getBirthDate()));
        }

        // 设置默认值
        if (datingMember.getRegistrationDate() == null)
        {
            datingMember.setRegistrationDate(new Date());
        }
        if (StringUtils.isEmpty(datingMember.getMemberStatus()))
        {
            datingMember.setMemberStatus("1"); // 默认正常状态
        }
        if (datingMember.getVipLevel() == null)
        {
            datingMember.setVipLevel(0L); // 默认普通会员
        }

        // 自动填充字段：createTime、createBy、updateTime、updateBy、delFlag
        return datingMemberMapper.insert(datingMember);
    }

    /**
     * 修改婚恋人员信息
     *
     * @param datingMember 婚恋人员信息
     * @return 结果
     */
    @Override
    public int updateDatingMember(DatingMember datingMember)
    {
        // 校验人员编号唯一性（排除自己）
        if (!checkMemberNoUnique(datingMember))
        {
            throw new ServiceException("修改人员'" + datingMember.getRealName() + "'失败，人员编号已存在");
        }

        // 校验手机号唯一性（排除自己）
        if (!checkPhoneUnique(datingMember))
        {
            throw new ServiceException("修改人员'" + datingMember.getRealName() + "'失败，手机号码已存在");
        }

        // 根据生日自动更新年龄
        if (datingMember.getBirthDate() != null)
        {
            datingMember.setAge(calculateAge(datingMember.getBirthDate()));
        }

        // 自动填充字段：updateTime、updateBy
        return datingMemberMapper.updateById(datingMember);
    }

    /**
     * 批量删除婚恋人员信息
     *
     * @param memberIds 需要删除的婚恋人员信息主键
     * @return 结果
     */
    @Override
    public int deleteDatingMemberByMemberIds(Long[] memberIds)
    {
        return datingMemberMapper.deleteBatchIds(Arrays.asList(memberIds));
    }

    /**
     * 删除婚恋人员信息信息
     *
     * @param memberId 婚恋人员信息主键
     * @return 结果
     */
    @Override
    public int deleteDatingMemberByMemberId(Long memberId)
    {
        return datingMemberMapper.deleteById(memberId);
    }

    /**
     * 校验人员编号是否唯一
     *
     * @param datingMember 人员信息
     * @return 结果
     */
    @Override
    public boolean checkMemberNoUnique(DatingMember datingMember)
    {
        // 使用XML映射的方法来检查人员编号唯一性
        int count = datingMemberMapper.checkMemberNoUnique(datingMember.getMemberNo());

        // 如果是更新操作，需要排除自己
        if (datingMember.getMemberId() != null && count > 0) {
            // 查询是否是当前记录本身
            DatingMember existMember = datingMemberMapper.selectDatingMemberByMemberNo(datingMember.getMemberNo());
            if (existMember != null && existMember.getMemberId().equals(datingMember.getMemberId())) {
                return true; // 是当前记录本身，允许
            }
        }

        return count == 0;
    }

    /**
     * 校验手机号码是否唯一
     *
     * @param datingMember 人员信息
     * @return 结果
     */
    @Override
    public boolean checkPhoneUnique(DatingMember datingMember)
    {
        // 使用XML映射的方法来检查手机号码唯一性
        int count = datingMemberMapper.checkPhoneUnique(datingMember.getPhone());

        // 如果是更新操作，需要排除自己
        if (datingMember.getMemberId() != null && count > 0) {
            // 查询是否是当前记录本身
            DatingMember existMember = datingMemberMapper.selectDatingMemberByPhone(datingMember.getPhone());
            if (existMember != null && existMember.getMemberId().equals(datingMember.getMemberId())) {
                return true; // 是当前记录本身，允许
            }
        }

        return count == 0;
    }

    /**
     * 导入人员数据
     *
     * @param memberList 人员数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    public String importMember(List<DatingMember> memberList, Boolean isUpdateSupport, String operName)
    {
        if (StringUtils.isNull(memberList) || memberList.size() == 0)
        {
            throw new ServiceException("导入人员数据不能为空！");
        }

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (DatingMember member : memberList)
        {
            try
            {
                // 验证是否存在这个人员
                DatingMember m = datingMemberMapper.selectDatingMemberByMemberNo(member.getMemberNo());
                if (StringUtils.isNull(m))
                {
                    BeanValidators.validateWithException(validator, member);
                    member.setCreateBy(operName);
                    this.insertDatingMember(member);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、人员 " + member.getRealName() + " 导入成功");
                }
                else if (isUpdateSupport)
                {
                    BeanValidators.validateWithException(validator, member);
                    member.setMemberId(m.getMemberId());
                    member.setUpdateBy(operName);
                    this.updateDatingMember(member);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、人员 " + member.getRealName() + " 更新成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、人员 " + member.getRealName() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、人员 " + member.getRealName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }

        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }

        return successMsg.toString();
    }

    /**
     * 生成人员编号
     */
    private String generateMemberNo()
    {
        // 格式：M + 年月日 + 4位序号
        String dateStr = DateUtils.dateTimeNow("yyyyMMdd");
        String prefix = "M" + dateStr;

        // 这里可以查询数据库获取当天最大序号，简化处理用时间戳后4位
        String timeSeq = String.valueOf(System.currentTimeMillis()).substring(9);

        return prefix + String.format("%04d", Integer.valueOf(timeSeq) % 10000);
    }

    /**
     * 根据生日计算年龄
     */
    private Long calculateAge(Date birthDate)
    {
        if (birthDate == null)
        {
            return null;
        }

        LocalDate birth = birthDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate now = LocalDate.now();

        return (long) Period.between(birth, now).getYears();
    }

    /**
     * 获取婚恋平台统计数据
     */
    @Override
    public DatingStatisticsVO getStatistics()
    {
        try {
            // 获取基础统计数据
            Long totalMembers = datingMemberMapper.countTotalMembers();
            Long todayNew = datingMemberMapper.countTodayNew();
            Long maleCount = datingMemberMapper.countByGender("0");
            Long femaleCount = datingMemberMapper.countByGender("1");
            Long matchesToday = datingMemberMapper.countTodayMatches();

            // 计算男性占比
            Double maleRatio = 0.0;
            Long total = maleCount + femaleCount;
            if (total > 0) {
                maleRatio = (maleCount.doubleValue() / total.doubleValue()) * 100;
            }

            return new DatingStatisticsVO(totalMembers, todayNew, maleRatio, matchesToday);
        } catch (Exception e) {
            log.error("获取统计数据失败", e);
            return new DatingStatisticsVO(0L, 0L, 0.0, 0L);
        }
    }

    /**
     * 获取每日人员增长统计
     */
    @Override
    public DatingGrowthVO getDailyGrowth(int days)
    {
        try {
            List<String> dates = new ArrayList<>();
            List<Long> maleData = new ArrayList<>();
            List<Long> femaleData = new ArrayList<>();
            List<Long> totalData = new ArrayList<>();

            LocalDate endDate = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");

            for (int i = days - 1; i >= 0; i--) {
                LocalDate date = endDate.minusDays(i);
                String dateStr = date.format(formatter);
                String fullDateStr = date.toString();

                Long maleCount = datingMemberMapper.countNewMembersByDateAndGender(fullDateStr, "0");
                Long femaleCount = datingMemberMapper.countNewMembersByDateAndGender(fullDateStr, "1");
                Long totalCount = maleCount + femaleCount;

                dates.add(dateStr);
                maleData.add(maleCount);
                femaleData.add(femaleCount);
                totalData.add(totalCount);
            }

            return new DatingGrowthVO(dates, maleData, femaleData, totalData);
        } catch (Exception e) {
            log.error("获取增长统计数据失败", e);
            return new DatingGrowthVO(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
        }
    }

    /**
     * 获取性别分布统计
     */
    @Override
    public DatingGenderVO getGenderDistribution()
    {
        try {
            Long maleCount = datingMemberMapper.countByGender("0");
            Long femaleCount = datingMemberMapper.countByGender("1");

            return new DatingGenderVO(maleCount, femaleCount);
        } catch (Exception e) {
            log.error("获取性别分布统计数据失败", e);
            return new DatingGenderVO(0L, 0L);
        }
    }

    /**
     * 获取年龄分布统计
     */
    @Override
    public DatingAgeVO getAgeDistribution()
    {
        try {
            List<String> ageRanges = Arrays.asList("18-25", "26-30", "31-35", "36-40", "40+");
            List<Long> maleCounts = new ArrayList<>();
            List<Long> femaleCounts = new ArrayList<>();

            // 18-25岁
            maleCounts.add(datingMemberMapper.countByAgeRangeAndGender(18, 25, "0"));
            femaleCounts.add(datingMemberMapper.countByAgeRangeAndGender(18, 25, "1"));

            // 26-30岁
            maleCounts.add(datingMemberMapper.countByAgeRangeAndGender(26, 30, "0"));
            femaleCounts.add(datingMemberMapper.countByAgeRangeAndGender(26, 30, "1"));

            // 31-35岁
            maleCounts.add(datingMemberMapper.countByAgeRangeAndGender(31, 35, "0"));
            femaleCounts.add(datingMemberMapper.countByAgeRangeAndGender(31, 35, "1"));

            // 36-40岁
            maleCounts.add(datingMemberMapper.countByAgeRangeAndGender(36, 40, "0"));
            femaleCounts.add(datingMemberMapper.countByAgeRangeAndGender(36, 40, "1"));

            // 40+岁
            maleCounts.add(datingMemberMapper.countByAgeRangeAndGender(41, 100, "0"));
            femaleCounts.add(datingMemberMapper.countByAgeRangeAndGender(41, 100, "1"));

            return new DatingAgeVO(ageRanges, maleCounts, femaleCounts);
        } catch (Exception e) {
            log.error("获取年龄分布统计数据失败", e);
            List<String> ageRanges = Arrays.asList("18-25", "26-30", "31-35", "36-40", "40+");
            List<Long> emptyCounts = Arrays.asList(0L, 0L, 0L, 0L, 0L);
            return new DatingAgeVO(ageRanges, new ArrayList<>(emptyCounts), new ArrayList<>(emptyCounts));
        }
    }

    /**
     * 获取收入分布统计
     */
    @Override
    public DatingIncomeVO getIncomeDistribution()
    {
        try {
            List<String> incomeRanges = Arrays.asList("3k以下", "3k-5k", "5k-8k", "8k-12k", "12k-20k", "20k以上");
            List<Long> counts = new ArrayList<>();

            // 3k以下
            counts.add(datingMemberMapper.countByIncomeRange(0, 3000));

            // 3k-5k
            counts.add(datingMemberMapper.countByIncomeRange(3000, 5000));

            // 5k-8k
            counts.add(datingMemberMapper.countByIncomeRange(5000, 8000));

            // 8k-12k
            counts.add(datingMemberMapper.countByIncomeRange(8000, 12000));

            // 12k-20k
            counts.add(datingMemberMapper.countByIncomeRange(12000, 20000));

            // 20k以上
            counts.add(datingMemberMapper.countByIncomeRange(20000, 999999));

            return new DatingIncomeVO(incomeRanges, counts);
        } catch (Exception e) {
            log.error("获取收入分布统计数据失败", e);
            List<String> incomeRanges = Arrays.asList("3k以下", "3k-5k", "5k-8k", "8k-12k", "12k-20k", "20k以上");
            List<Long> emptyCounts = Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L);
            return new DatingIncomeVO(incomeRanges, new ArrayList<>(emptyCounts));
        }
    }
}
